// @ts-nocheck
const path = require("path");
const fs = require("fs");
const { createResponse, validatePaginationParams, handlePagination, handleError, handleJson } = require("./common.js");
const { validateModelPath, getModelContentType, isValidModelCategory, isValidModelExtension } = require("./modelTools.js");
const crypto = require("crypto");
const { searchData } = require("./search.js");

const BASE_PATH = path.join(__dirname, "GLBS");
const validTokens = new Set();
 class jsonClass {
  async validateToken(ctx, next) {
    try {
      // 从请求头获取token
      const authHeader = ctx.headers.authorization;
      const token = authHeader && authHeader.startsWith("Bearer ") ? authHeader.slice(7) : null;
      // 检查token是否存在且有效
      if (!token || !validTokens.has(token)) {
        ctx.status = 401;
        ctx.body = createResponse(false, 401, "未授权访问，请先登录");
        return;
      }
      // token有效，继续执行下一个中间件
      await next();
    } catch (err) {
      console.error(err);
      ctx.status = 401;
      ctx.body = createResponse(false, 401, "Token验证失败");
    }
  }
  createFullPath(ctx, reqPath) {
    console.log(reqPath, "reqPath");
    let fullPath = path.join(BASE_PATH, reqPath);
    fullPath = path.normalize(fullPath);
    // 确保路径在GLBS目录内
    if (!fullPath.startsWith(BASE_PATH)) {
      ctx.throw(403, "只能访问GLBS目录内容");
      throw new Error("只能访问GLBS目录内容");
    }
    // 检查文件是否存在
    if (!fs.existsSync(fullPath)) {
      console.log(fullPath);
      ctx.throw(404, "文件不存在");
      throw new Error("文件不存在");
    }
    return fullPath;
  }
  readJsonFile(filePath) {
    const fileContent = fs.readFileSync(filePath, "utf8");
    return JSON.parse(fileContent);
  }
  pageCommon(ctx, search) {
    const filePath = ctx.state.fullPath;
    // 读取JSON文件内容
    let jsonData = this.readJsonFile(filePath);
    // 验证分页参数
    const validation = validatePaginationParams(ctx.query.current, ctx.query.size);
    if (!validation.isValid) {
      ctx.body = createResponse(false, 400, validation.error);
      return;
    }
    if (search) {
      jsonData = search(jsonData);
    }
    return handlePagination(jsonData, validation.page, validation.pageSize);
  }
  async getDict(ctx) {
    try {
      // 读取JSON文件内容
      if (this.pageCommon(ctx)) {
        ctx.body = createResponse(
          true,
          200,
          "获取数据成功",
          this.pageCommon(ctx, (jsonData) => (ctx.query.label ? searchData(jsonData, ctx.query.label, ["label"]) : jsonData)).data
        );
      }
    } catch (err) {
      handleError(ctx, err, "读取JSON文件");
    }
  }
  async getJson(ctx) {
    try {
      if (this.pageCommon(ctx)) {
        ctx.body = createResponse(true, 200, "获取数据成功", this.pageCommon(ctx).data);
      }
    } catch (err) {
      handleError(ctx, err, "读取JSON文件");
    }
  }
  // 安全中间件 - 验证路径合法性
  async validatePath(ctx, next) {
    try {
      let reqPath = "";
      console.log(ctx.params, ctx.request.url, ctx.query, "validatePath", this);
      if (ctx.params.dict) {
        reqPath = "dict/" + ctx.params.dict;
      } else if (ctx.params.path) {
        reqPath = ctx.params.path;
      } else {
        reqPath = ctx.query.path || "";
      }
      // 解码URL编码的中文字符
      reqPath = decodeURIComponent(reqPath);
      // 安全检查
      if (reqPath.includes("../") || reqPath.includes("..\\")) {
        ctx.throw(400, "非法路径请求");
        return;
      }
      // 自动添加 json/ 文件夹路径
      if (!reqPath.startsWith("json/")) {
        reqPath = "json/" + reqPath;
      }
      // 自动添加 .json 后缀
      if (!reqPath.endsWith(".json")) {
        reqPath += ".json";
      }
      // 构建完整路径
      let fullPath = this.createFullPath(ctx, reqPath);
      console.log(fullPath, "文件路径");
      ctx.state.fullPath = fullPath;
      await next();
    } catch (err) {
      console.error(`路径验证错误: ${err}`);
    }
  }
  async getModel(ctx) {
    try {
      // 使用正则表达式捕获参数
      const category = decodeURIComponent(ctx.captures[0]); // 第一个捕获组：分类
      const filePath = decodeURIComponent(ctx.captures[1]); // 第二个捕获组：文件路径（URL解码）
      // 验证路径
      const validation = validateModelPath(category, filePath, path, BASE_PATH);
      if (!validation.isValid) {
        ctx.status = validation.statusCode;
        ctx.body = createResponse(false, validation.statusCode, validation.error);
        return;
      }
      const { normalizedPath, filename } = validation;
      // 检查文件是否存在
      if (!fs.existsSync(normalizedPath)) {
        ctx.status = 404;
        ctx.body = createResponse(false, 404, "文件不存在", {
          category,
          filePath,
          fullPath: normalizedPath,
        });
        return;
      }
      const stats = fs.statSync(normalizedPath);
      // 确保是文件而不是目录
      if (stats.isDirectory()) {
        ctx.status = 400;
        ctx.body = createResponse(false, 400, "请求路径是目录而不是文件");
        return;
      }
      // 设置适当的Content-Type
      const contentType = getModelContentType(filename, path);
      // 设置响应头
      ctx.set("Content-Type", contentType);
      ctx.set("Content-Length", stats.size);
      ctx.set("Content-Disposition", `inline; filename="${filename}"`);
      ctx.set("Cache-Control", "public, max-age=3600"); // 缓存1小时
      // 创建文件流并返回
      ctx.body = fs.createReadStream(normalizedPath);
    } catch (err) {
      handleError(ctx, err, "获取模型文件");
    }
  }
  async login(ctx) {
    try {
      const { username, password } = ctx.request.body;
      // 校验账号密码
      if (username === "admin" && password === "123456") {
        const token = crypto.randomUUID();
        validTokens.add(token);
        ctx.body = createResponse(true, 200, "登录成功", token);
      } else {
        ctx.status = 401;
        ctx.body = createResponse(false, 401, "用户名或密码错误");
      }
    } catch (err) {
      handleError(ctx, err, "登录");
    }
  }
  handleCommon(ctx, path) {
    const filePath = this.createFullPath(ctx, path);
    const operation = ctx.params.operation;
    let jsonData = {};
    // 如果文件存在，读取现有内容
    if (fs.existsSync(filePath)) {
      jsonData = this.readJsonFile(filePath);
    } else {
      ctx.body = createResponse(false, 500, "文件路径不存在，不可操作");
      return;
    }
    return {
      jsonData,
      filePath,
      operation,
    };
  }
  writeFile(filePath, data) {
    fs.writeFileSync(filePath, JSON.stringify(data));
  }
  async handleBinary(ctx) {
    try {
      const data = ctx.request.body;
      const isNormal = this.handleCommon(ctx, `json/${data.fileName}.json`);
      if (isNormal) {
        const { jsonData, filePath, operation } = isNormal;
        const resultData = handleJson(jsonData, operation, data.json);
        if (resultData.success) {
          this.writeFile(filePath, resultData.data);
          resultData.data = null;
        }
        ctx.body = resultData;
      }
    } catch (err) {
      handleError(ctx, err, "处理题库");
    }
  }
  
  async createJsonFile(ctx) {
    try {
      const { fileName, content } = ctx.request.body;
      // Validate inputs
      if (!fileName) {
        ctx.body = createResponse(false, 400, "文件名不能为空");
        return;
      }
      // Construct and validate file path
      const filePath = path.join(BASE_PATH, "json", `${fileName}.json`);
      if (!filePath.startsWith(BASE_PATH)) {
        ctx.body = createResponse(false, 403, "只能在GLBS目录内创建文件");
        return;
      }
      // Check if file already exists
      if (fs.existsSync(filePath)) {
        ctx.body = createResponse(false, 409, "文件已存在");
        return;
      }
      // Prepare content (default to empty object if not provided)
      const fileContent = content ? (typeof content === 'string' ? JSON.parse(content) : content) : {};
      // Create the file
      this.writeFile(filePath, fileContent);
      ctx.body = createResponse(true, 200, "文件创建成功", { filePath });
    } catch (err) {
      handleError(ctx, err, "创建JSON文件");
    }
  }
  
  async logout(ctx) {
    try {
      validTokens.clear();
      ctx.body = createResponse(true, 200, "登出成功");
    } catch (err) {
      handleError(ctx, err, "登出");
    }
  }
}

module.exports = jsonClass;